home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 427_01 / software / minijoy.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1994-03-23  |  7.2 KB  |  247 lines

  1. unit minijoy; (* reads out status of the MULTI JOYSTICK INTERFACE *)
  2.  
  3.               (* Demo unit lacking
  4.                  - keyboard support
  5.                  - joystick reassignment
  6.                  - disabling if no MULTIJOY is wanted *)
  7.  
  8. (* MINIJOY uses three DOS environment variables:
  9.  
  10.    MULTIPATH is the path where the config file is located
  11.    MULTICFG  is the name of the config file without extension
  12.    MULTIPORT is optional and states the printer port to be used
  13.              (port 1 is the default if MULTIPORT is empty)         *)
  14.  
  15.  
  16. interface
  17.  
  18.  
  19. const maxplayer = 6;             (* maximum number of players *)
  20.  
  21.  
  22. type TJoy = record
  23.               x, y         : shortint; (* -1 .. +1 (minus is left/up) *)
  24.               lhit,  rhit,             (* directions triggered?       *)
  25.               uhit,  dhit,             (* directions triggered?       *)
  26.               khit,  xhit,             (* buttons triggered?          *)
  27.               knopf, xtra  : boolean;  (* buttons held down?          *)
  28.             end;
  29.  
  30.      TJoyState  = array [1 .. maxplayer] of TJoy;
  31.  
  32. var  JoyState   : TJoyState;
  33.      (* contains all joystick status information *)
  34.      (* is updated by calling GetAllJoyState     *)
  35.  
  36.  
  37. procedure InitMultiJoy;
  38. (* MINIJOY initializes itself, but you can initialize again if you want *)
  39.  
  40. procedure GetAllJoyState;
  41. (* gets status of all joystick ports *)
  42.  
  43.  
  44. implementation
  45.  
  46.  
  47. uses crt, dos, multierr;
  48.  
  49. type TDecode  = record
  50.                   stikno1 : byte;
  51.                   action1 : char;
  52.                   stikno2 : byte;
  53.                   action2 : char;
  54.                 end;
  55.  
  56. const zero_action : TJoy
  57.                   = (x     : 0    ; y    : 0;
  58.                      lhit  : false; rhit : false;
  59.                      uhit  : false; dhit : false;
  60.                      khit  : false; xhit : false;
  61.                      knopf : false; xtra : false);
  62.       actionchars = (['L', 'R', 'U', 'D', 'F', '*']);
  63.  
  64. var multipath    : string;
  65.     multicfg     : string [8];
  66.     multiport    : string [1];
  67.     multidelay   : string [5];
  68.     printer_port : byte;
  69.     pout,
  70.     p_in         : word;
  71.     decode       : array [0 .. 15] of TDecode;
  72.     keyboard,
  73.     invert       : boolean;
  74.     delaycount   : word;
  75.  
  76.  
  77. function read_port (mjoyaddress : byte) : byte;
  78. (* sets MULTI JOYSTICK INTERFACE to address MJOYADDRESS *)
  79. (* reads printer port, i.e. PAPER EMPTY and BUSY bits   *)
  80. begin
  81.   port [pout] := mjoyaddress;
  82.   asm
  83.     mov  cx, delaycount
  84.   @l:
  85.     nop
  86.     loop @l
  87.   end;
  88.   if invert then read_port := not port [p_in]
  89.             else read_port :=     port [p_in];
  90. end;
  91.  
  92.  
  93. procedure error_msg (msg_nr, code : integer);
  94. (* calls MULTIERR error message procedure *)
  95. begin
  96.   multierr.error_msg (msg_nr, code, multipath, multicfg, multiport);
  97. end;
  98.  
  99.  
  100. procedure InitMultiJoy;
  101. (* reads interface pin assignment from disk *)
  102. (* resets joystick status variables         *)
  103. var cmdline   : string [8];
  104.     cfg       : text;
  105.     i,
  106.     j,
  107.     k,
  108.     error     : integer;
  109.     dummy     : char;
  110.  
  111.  
  112.   function get_port_no (port_no : char) : byte;
  113.   (* find printer port number in a string *)
  114.   begin
  115.     if not (port_no in ['1' .. '3']) then error_msg (8, ord (port_no));
  116.     get_port_no := ord(port_no)-ord('0');
  117.   end;
  118.  
  119.  
  120. begin
  121.   multipath := getenv ('multipath'); (* read environment variables *)
  122.   multicfg  := getenv ('multicfg' );
  123.   multiport := getenv ('multiport');
  124.   multidelay:= getenv ('multidelay');
  125.   if multidelay<>'' then begin
  126.     val(multidelay,delaycount,error);
  127.     if error<>0 then error_msg (13,0);
  128.     inc(delaycount);
  129.   end else
  130.     delaycount:=1;
  131.  
  132.   if multiport = ''  then printer_port := 1 (* default!   *)
  133.                      else printer_port := get_port_no (multiport [1]);
  134.  
  135.   pout := memw [$40:$8 + (printer_port-1) * 2];
  136.   if pout = 0 then error_msg (11, printer_port);
  137.   p_in := pout + 1;
  138.  
  139.   if multipath           = ''  then error_msg (5, 0); (* undefined? *)
  140.   if multicfg            = ''  then error_msg (6, 0); (* undefined? *)
  141.   if pos ('.', multicfg) >  0  then error_msg (7, 0); (* extension? *)
  142.  
  143.   if multipath[length(multipath)]='\' then
  144.     assign (cfg, multipath + multicfg + '.cfg')
  145.   else
  146.     assign (cfg, multipath + '\' + multicfg + '.cfg');
  147.  
  148.   {$I-}
  149.   reset(cfg);
  150.   {$I+}
  151.   error := ioresult;
  152.   if error <> 0 then error_msg (1, error);
  153.  
  154.   readln (cfg, cmdline);
  155.   if (cmdline = 'keyboard') or (cmdline = 'KEYBOARD') then error_msg (9, 0);
  156.  
  157.   (* read config file *)
  158.   reset (cfg);
  159.   for i := 0 to 15 do begin
  160.     with decode [i] do begin
  161.       if eof (cfg) then error_msg (3, 0);
  162.       {$I-}
  163.       readln (cfg, j, stikno1, dummy, action1, stikno2, dummy, action2);
  164.       {$I+}
  165.       error := ioresult;
  166.       if error <> 0 then error_msg (4, error);
  167.       if (stikno1 < 1) or (stikno1 > maxplayer) then error_msg (12, stikno1);
  168.       action1 := upcase (action1);
  169.       if not (action1 in actionchars) then error_msg (2, ord (action1));
  170.       if (stikno2 < 1) or (stikno2 > maxplayer) then error_msg (12, stikno2);
  171.       action2 := upcase (action2);
  172.       if not (action2 in actionchars) then error_msg (2, ord (action2));
  173.     end;
  174.   end;
  175.   if not eof (cfg) then readln (cfg, cmdline)
  176.                    else cmdline := '';
  177.   if (cmdline = 'invert') or (cmdline = 'INVERT') then invert := true
  178.                                                   else invert := false;
  179.   close (cfg);
  180.  
  181.   (* initialize joystick status variables *)
  182.   for i:=1 to maxplayer do JoyState [i] := zero_action;
  183. end;
  184.  
  185.  
  186. procedure GetAllJoyState;
  187. (* gets status of all joysticks *)
  188. var address,
  189.     joy,
  190.     joy_now,
  191.     player,
  192.     pebu     : byte; (* PAPER EMPTY and BUSY bits *)
  193.     old      : array [1 .. maxplayer] of record
  194.                                            ox,
  195.                                            oy : shortint;
  196.                                            ok,
  197.                                            oe : boolean;
  198.                                           end;
  199.  
  200.  
  201.   procedure decode_joystate (decode_action : char);
  202.   (* decodes joystick status *)
  203.   begin
  204.     with joystate [joy_now] do
  205.       with old [joy_now] do begin
  206.         case decode_action of
  207.           'L' : begin x := - 1; lhit := - 1 <> ox;   end;
  208.           'R' : begin x :=   1; rhit :=   1 <> ox;   end;
  209.           'U' : begin y := - 1; uhit := - 1 <> oy;   end;
  210.           'D' : begin y :=   1; dhit :=   1 <> oy;   end;
  211.           'F' : begin knopf := true; khit := not ok; end;
  212.           '*' : begin xtra  := true; xhit := not oe; end;
  213.         end;
  214.     end;
  215.   end;
  216.  
  217.  
  218. (* GetAllJoyState *)
  219. var i : integer;
  220. begin
  221.   for joy := 1 to maxplayer do begin
  222.     with JoyState [joy] do
  223.       with old [joy] do begin
  224.         ox := x;
  225.         oy := y;
  226.         ok := knopf;
  227.         oe := xtra;
  228.       end;
  229.     JoyState [joy] := zero_action;
  230.   end;
  231.  
  232.   for address := 0 to 15 do begin
  233.     pebu := read_port (address);
  234.     (* first bit *)
  235.     joy_now := decode [address].stikno1;
  236.     if (pebu and $20) <> 0 then decode_joystate (decode [address].action1);
  237.     (* second bit *)
  238.     joy_now := decode [address].stikno2;
  239.     if (pebu and $80) =  0 then decode_joystate (decode [address].action2);
  240.   end;
  241. end;
  242.  
  243.  
  244. (* MultiJoy *)
  245. begin
  246.   InitMultiJoy;
  247. end.